package common.helper.json;

import java.io.File;
import java.io.IOException;

import common.model.document.MediaAsset;
import common.helper.serialization.CustomDate;
import common.helper.serialization.CustomDateDeserializer;
import common.helper.serialization.CustomDateSerializer;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class JsonValidation {
	public final ObjectMapper mapper = new ObjectMapper();
	
	public static void main(String[] args){
		/////////////////////////////////
		/*
		 * backup Date
		 */
		/*
		Date now = new Date();
		System.out.println(now);
		long nowInMill = now.getTime();
		
		CustomDate now2 = new CustomDate(nowInMill);
		System.out.println(now2);
		
		System.out.println(new CustomDate());
		
		long time = 1262275200000L;
		System.out.println(new Date(time));
		System.out.println(new CustomDate(time));
		*/
		
		//////////////////////////////////
		
		
		JsonValidation obj = new JsonValidation();
		//obj.mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
		/*
		SimpleModule simpleMoudle = new SimpleModule();
		simpleMoudle.addDeserializer(CustomDate.class, new CustomDateDeserializer());
		simpleMoudle.addSerializer(CustomDate.class, new CustomDateSerializer());
		obj.mapper.registerModule(simpleMoudle);
		*/
		obj.configMapper();
		/*
		if(args.length != 1){
			System.out.println("Please Input Json Dictionary!");
		}
		else{
			obj.getAllFiles(args[0]);
		}
		*/
		String filePath = "";
		
		filePath = "/Users/julian/Home/DataBase/jsonPath";
		obj.runFolder(filePath);
		
		/*
		filePath = "/Users/julian/Home/DataBase/json_result";
		obj.runFolder(filePath);
		*/
		
		//filePath = "/Users/julian/Home/DataBase/json_result2";
		//obj.runFolder(filePath);
		
	}
	
	public void runFolder(String filePath){
		getAllFiles(filePath);
		getFirstFile(filePath);
	}
	
	public void configMapper(){
		//registe moudle
		SimpleModule simpleMoudle = new SimpleModule();
		simpleMoudle.addDeserializer(CustomDate.class, new CustomDateDeserializer());
		//addSerializer doesn't work, I don't known why.
		//but it doesn't matter since we only need to deserialize Json to Java
		//WRITE_DATES_AS_TIMESTAMPS = false , also doesn't work
		simpleMoudle.addSerializer(CustomDate.class, new CustomDateSerializer());
		//simpleMoudle.addSerializer(new CustomDateSerializer());
		mapper.registerModule(simpleMoudle);
		
		//ACCEPT_SINGLE_VALUE_AS_ARRAY
		//http://wiki.fasterxml.com/JacksonFeaturesDeserialization
		//http://fasterxml.github.io/jackson-databind/javadoc/2.0.2/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY
		mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
		
		//WRITE_DATES_AS_TIMESTAMPS
		//http://wiki.fasterxml.com/JacksonFeaturesSerialization
		mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
		
		//SerializationFeature.FAIL_ON_EMPTY_BEANS
		mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
	}
	
	private void getAllFiles(String filePath){
		int total = 0;
		int valid = 0;
		File root = new File(filePath);
		File[] files = root.listFiles();
		for(File file : files){
			if(file.getName().equals(".DS_Store")) continue;
			else if(file.isDirectory()){
				getAllFiles(file.getAbsolutePath());
			}
			else{
				total ++;
				System.out.println("+++++ " + file.getAbsolutePath() + " +++++");
				
				if(Json2Object(file) == true){
					valid ++;
					System.out.println("----- " + "Success" + " -----");
				}
				else{
					System.out.println("----- " + "Failure" + " -----");
				}
				System.out.println("");
			}
		}
		
		System.out.println("Total: " + total);
		System.out.println("Valid: " + valid);
		
		System.out.println("");
		System.out.println("");
		
	}
	
	private void getFirstFile(String filePath){
		String FileName = "";
		File root = new File(filePath);
		File[] files = root.listFiles();
		for(File file : files){
			if(file.getName().equals(".DS_Store")) continue;
			else if(file.isDirectory()){
				getAllFiles(file.getAbsolutePath());
			}
			else{
				//total ++;
				FileName = file.getAbsolutePath();
				System.out.println("+++++ " + file.getAbsolutePath() + " +++++");
				
				if(Json2Object(file) == true){
					//valid ++;
					System.out.println("----- " + "Success" + " -----");
				}
				else{
					System.out.println("----- " + "Failure" + " -----");
					break;
				}
				System.out.println("");
			}
		}
		
		System.out.println("");
		System.out.println("");
		System.out.println("Failure");
		System.out.println("Failure");
		System.out.println("Failure: " + FileName);
		System.out.println("");
		System.out.println("");
		
	}
	
	private boolean Json2Object(File jsonFile){
		 try{
			 
			 MediaAsset mediaAsset = mapper.readValue(jsonFile, MediaAsset.class);
			 
			 System.out.println("JsonMappingSuccess: " + jsonFile.getAbsolutePath());
			 System.out.println(mediaAsset.toString());
			 return true;
		 } catch (JsonParseException e) {  
			 System.out.println("JsonParseException: " + jsonFile.getAbsolutePath());
		     e.printStackTrace();
		 } catch (JsonMappingException e) {  
			 System.out.println("JsonMappingException: " + jsonFile.getAbsolutePath());
		     e.printStackTrace();  
		 } catch (IOException e) {  
			 System.out.println("IOException: " + jsonFile.getAbsolutePath());
		     e.printStackTrace();  
		 }
		 return false;
	}

}
